#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
洪水预报智能代理

基于LangChain Agent框架实现的智能对话代理，整合参数提取和验证功能
"""

from langchain.agents import AgentExecutor, create_react_agent
from langchain.prompts import PromptTemplate
from langchain.agents.output_parsers import ReActSingleInputOutputParser
from langchain.agents.format_scratchpad import format_log_to_str
from langchain.schema import AgentAction, AgentFinish
from langchain.memory import ConversationBufferMemory
import re
# from langchain_openai import ChatOpenAI  # 已删除OpenAI支持
from langchain_community.llms import Ollama
from langchain_community.chat_models import ChatOllama
from langchain.schema import HumanMessage, AIMessage, SystemMessage
from typing import Dict, Any, List, Optional, Tuple, Union
import json
from loguru import logger
from datetime import datetime


# 导入自定义工具
# 在文件顶部添加导入
from parameter_update_tool import ParameterUpdateTool
from session_completion_tool import SessionCompletionTool

# 导入配置
try:
    from config.config import OLLAMA_CONFIG
except ImportError:
    # 如果配置文件不存在，使用默认配置
    OLLAMA_CONFIG = {
        "base_url": "http://10.48.0.81:11434",
        "embedding_model": "bge-m3:latest",
        "chat_model": "qwq:latest"
    }

class QwqReActOutputParser(ReActSingleInputOutputParser):
    """自定义输出解析器，兼容qwq模型的<think>标签"""
    
    def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
        """解析Agent输出，处理<think>标签"""
        # 移除<think>标签及其内容，但保留其他部分
        cleaned_text = re.sub(r'<think>.*?</think>', '', text, flags=re.DOTALL)
        
        # 调用父类的解析方法
        try:
            return super().parse(cleaned_text)
        except Exception as e:
            # 如果解析失败，尝试更激进的清理
            logger.warning(f"首次解析失败，尝试更激进的清理: {e}")
            
            # 提取最后的Action和Action Input
            action_match = re.search(r'Action:\s*([^\n]+)', cleaned_text)
            action_input_match = re.search(r'Action Input:\s*([^\n]+)', cleaned_text)
            
            if action_match and action_input_match:
                action = action_match.group(1).strip()
                action_input = action_input_match.group(1).strip()
                
                # 尝试解析action_input为JSON
                try:
                    import json
                    if action_input.startswith('{') and action_input.endswith('}'):
                        action_input_dict = json.loads(action_input)
                    else:
                        action_input_dict = action_input
                except:
                    action_input_dict = action_input
                
                return AgentAction(tool=action, tool_input=action_input_dict, log=text)
            
            # 检查是否是Final Answer
            final_answer_match = re.search(r'Final Answer:\s*(.+)', cleaned_text, re.DOTALL)
            if final_answer_match:
                return AgentFinish(return_values={"output": final_answer_match.group(1).strip()}, log=text)
            
            # 如果都失败了，重新抛出异常
            raise e

class FloodForecastAgent:
    """洪水预报智能代理
    
    整合参数提取、验证和对话管理功能的智能代理
    """
    
    # 在__init__方法中添加新工具
    def __init__(self, 
                 llm_config: Dict[str, Any],
                 max_iterations: int = None,
                 max_execution_time: float = None):
        """
        初始化智能代理
        
        Args:
            llm_config: LLM配置信息
            max_iterations: 最大迭代次数
            max_execution_time: 最大执行时间（秒）
        """
        self.llm_config = llm_config
        self.max_iterations = max_iterations
        self.max_execution_time = max_execution_time
        
        # 初始化工具
        self.parameter_update_tool = ParameterUpdateTool(agent_instance=self)
        self.session_completion_tool = SessionCompletionTool(agent_instance=self)
        self.tools = [self.parameter_update_tool, self.session_completion_tool]
        
        # 初始化LLM
        self.llm = self._init_llm()
        
        # 状态管理
        self.collected_parameters = {}
        self.chat_history = []
        self.current_stage = "collection"  # collection, recommendation, modification, completed
        self.is_session_completed = False  # 标记会话是否已完成
        self.user_confirmed = False  # 添加用户确认状态跟踪
        
        # 初始化记忆功能
        self.memory = ConversationBufferMemory(
            memory_key="chat_history",
            return_messages=True,
            input_key="input",
            output_key="output"
        )
        
        # 延迟初始化agent executor
        self.agent_executor = None
    
    def _init_llm(self):
        """初始化LLM - 仅支持Ollama"""
        return ChatOllama(
            model=self.llm_config.get('model', OLLAMA_CONFIG['chat_model']),
            temperature=self.llm_config.get('temperature', 0.1),
            base_url=self.llm_config.get('base_url', OLLAMA_CONFIG['base_url'])
        )
    
    def _create_system_prompt(self) -> str:
        """动态创建系统提示词"""
        from datetime import datetime
        
        # 获取当前实际时间，确保大模型使用正确的时间信息
        current_time = datetime.now()
        current_time_str = current_time.strftime('%Y年%m月%d日 %H:%M:%S')
        current_date_str = current_time.strftime('%Y-%m-%d')
        
        # 基础系统提示
        base_prompt = f"""
你是一个专业的洪水预报参数推荐助手。你的任务是为用户提供洪水预报参数的推荐值，并通过确定/不确定的方式与用户交互。

重要时间信息：
- 当前实际时间：{current_time_str}
- 当前日期：{current_date_str}
- 请在所有时间相关的推理和计算中使用上述当前时间，而不是你训练数据中的时间
- 推荐的开始时间应该基于当前实际时间计算下一个整点时间

工作流程：
1. 用户提供水库名称
2. 你为其他5个参数提供默认推荐值
3. 询问用户是否确定这些推荐值
4. 如果用户不确定，询问需要修改哪个参数，然后提供新的推荐值
5. 重复确定/不确定的交互，直到用户满意

需要推荐的参数：
1. forecast_model (预报模型): 推荐"新安江模型"，必须是以下之一：新安江模型、LSTM模型、GRU模型、Transformer模型、XGBoost模型、Random Forest模型
2. start_time (开始时间): 推荐当前时间的下一个整点，格式为YYYY-MM-DD HH:00（不能早于今天，不能超过30天后）
3. forecast_duration (预报时长): 推荐48小时（1-168小时，即1小时到7天）
4. rainfall_forecast_period (降雨预见期): 推荐12小时（1-72小时，即1小时到3天）
5. target_variable (目标变量): 推荐"流量"，必须是以下之一：流量、水位、库容、入库流量、出库流量

参数验证规则：
- 水库名称：不能为空，长度不超过50个字符
- 预报模型：必须从指定的6种模型中选择
- 开始时间：格式必须正确，时间范围合理
- 预报时长：1-168小时之间的正整数
- 降雨预见期：1-72小时之间的正整数
- 目标变量：必须从指定的5种变量中选择

交互原则：
1. 当用户提供水库名称后，立即调用update_parameters工具更新水库名称
2. 然后为其他5个参数提供默认推荐值，并调用update_parameters工具更新
3. 向用户展示所有推荐参数，询问"这些推荐参数您确定吗？"
4. 如果用户说"确定"或类似表达，调用mark_session_completed工具，然后给出最终答案
5. 如果用户说"不确定"或要求修改，询问具体要修改哪个参数
6. 根据用户要求修改特定参数，然后再次询问是否确定
7. 保持简单的确定/不确定交互模式

重要规则：
- 当用户确认参数时（说"确定"、"好的"、"没问题"、"可以"、"同意"等），调用mark_session_completed工具
- 调用mark_session_completed工具后，给出最终确认信息
- 只有当用户提供新的参数信息时，才使用update_parameters工具
- 如果用户要求修改参数，使用update_parameters工具更新，然后再次询问确认
- 用户确认后，系统会自动生成JSON参数配置文件
- 如果用户提供的参数不在有效范围内，系统会自动提示错误信息，你需要引导用户提供正确的参数
- 当用户输入无效参数时，要友好地解释有效范围，并建议正确的选项

ReAct格式规则：
- 需要调用工具时：Thought: [简洁思考] → Action: [工具名称] → Action Input: [输入内容]
- 直接回复用户时：Thought: [简洁思考] → Final Answer: [回复内容]
- 用户确认时：Thought → Action: mark_session_completed → Action Input: confirmed: true → Observation → Final Answer
- 思考过程要简洁明了，避免冗长的分析

对话指导原则：
1. 使用自然、友好的语言与用户交流
2. 始终采用确定/不确定的询问方式
3. 提供清晰的推荐理由
4. 一次只修改用户要求的参数
5. 保持交互简单直接
"""
        
        # 根据当前阶段动态调整提示
        if self.current_stage == "collection":
            if not self.collected_parameters.get('reservoir_name'):
                base_prompt += "\n\n当前阶段：等待用户提供水库名称"
                base_prompt += "\n请询问用户需要预报哪个水库的洪水情况。"
            else:
                base_prompt += "\n\n当前阶段：提供参数推荐"
                base_prompt += "\n用户已提供水库名称，现在需要为其他5个参数提供推荐值并更新。"
                base_prompt += "\n推荐完成后询问用户是否确定这些参数。"
                base_prompt += f"\n注意：推荐开始时间时，请基于当前实际时间（{current_time_str}）计算下一个整点。"
        
        elif self.current_stage == "recommendation":
            base_prompt += "\n\n当前阶段：参数推荐确认"
            base_prompt += "\n已提供推荐参数，询问用户是否确定。"
            base_prompt += "\n如果用户确定，完成推荐；如果不确定，询问要修改哪个参数。"
            base_prompt += f"\n重要：所有时间相关的推理都应基于当前实际时间（{current_time_str}）。"
        
        elif self.current_stage == "modification":
            base_prompt += "\n\n当前阶段：参数修改"
            base_prompt += "\n用户要求修改某个参数，根据用户需求提供新的推荐值。"
            base_prompt += "\n修改完成后再次询问是否确定。"
            base_prompt += f"\n重要：修改时间相关参数时，请基于当前实际时间（{current_time_str}）进行计算。"
        
        elif self.current_stage == "completed":
            base_prompt += "\n\n当前阶段：推荐完成"
            base_prompt += "\n用户已确认所有参数，可以进行自由对话。"
        
        # 显示当前参数状态
        if self.collected_parameters:
            # 过滤掉内部字段
            filtered_params = {k: v for k, v in self.collected_parameters.items() 
                             if k not in ['extraction_confidence', 'raw_input']}
            params_json = json.dumps(filtered_params, ensure_ascii=False)
            # 转义花括号以避免模板变量冲突
            params_json = params_json.replace('{', '{{').replace('}', '}}')
            base_prompt += f"\n\n当前参数状态: {params_json}"
        
        elif self.current_stage == "completed":
            base_prompt += "\n\n当前阶段：已完成"
            base_prompt += "\n参数收集已完成！"
            base_prompt += "\n可以与用户进行自由对话，回答问题或提供帮助"
            base_prompt += "\n如果用户需要重新开始，请提示他们可以重置会话"
            # 过滤掉内部字段，避免在模板中产生变量冲突
            filtered_params = {k: v for k, v in self.collected_parameters.items() 
                             if k not in ['extraction_confidence', 'raw_input']}
            params_json = json.dumps(filtered_params, ensure_ascii=False)
            # 转义花括号以避免模板变量冲突
            params_json = params_json.replace('{', '{{').replace('}', '}}')
            base_prompt += f"\n已完成的参数: {params_json}"
        
        return base_prompt
    
    def _get_missing_parameters(self) -> List[str]:
        """获取缺失的参数列表"""
        required_params = ['reservoir_name', 'forecast_model', 'start_time', 
                          'forecast_duration', 'rainfall_forecast_period', 'target_variable']
        return [param for param in required_params 
                if param not in self.collected_parameters or 
                self.collected_parameters[param] is None]
    
    def _generate_default_recommendations(self) -> Dict[str, Any]:
        """生成默认推荐参数"""
        from datetime import datetime, timedelta
        import time
        
        # 获取当前精确的系统时间
        now = datetime.now()
        logger.info(f"当前系统时间: {now.strftime('%Y-%m-%d %H:%M:%S')}")
        
        # 计算下一个整点时间
        # 如果当前时间已经是整点（分钟和秒都为0），则推荐下一个小时
        # 否则推荐当前小时的下一个整点
        if now.minute == 0 and now.second == 0:
            next_hour = now + timedelta(hours=1)
        else:
            next_hour = now.replace(minute=0, second=0, microsecond=0) + timedelta(hours=1)
        
        recommended_time = next_hour.strftime('%Y-%m-%d %H:%M')
        logger.info(f"推荐的开始时间: {recommended_time}")
        
        recommendations = {
            'forecast_model': '新安江模型',
            'start_time': recommended_time,
            'forecast_duration': 48,
            'rainfall_forecast_period': 12,
            'target_variable': '流量'
        }
        
        logger.info(f"生成的推荐参数: {recommendations}")
        return recommendations
    
    def _init_agent_executor(self) -> AgentExecutor:
        """初始化Agent执行器 - 仅支持Ollama ReAct代理"""
        # 创建动态提示模板
        system_prompt = self._create_system_prompt()
        
        # 获取当前时间信息，确保在ReAct模板中也提供准确的时间
        from datetime import datetime
        current_time = datetime.now()
        current_time_info = f"当前实际时间：{current_time.strftime('%Y年%m月%d日 %H:%M:%S')}"
        
        # 创建ReAct提示模板，兼容qwq模型的<think>标签，并集成记忆功能
        template = f"""{system_prompt}

{current_time_info}

你有以下工具可以使用：
{{tools}}

对话历史：
{{chat_history}}

使用以下格式（可以使用<think>标签进行思考）：

Question: 用户的输入问题
<think>
你的详细思考过程，请参考对话历史来理解上下文和之前的交互。
重要：在进行任何时间相关的推理时，请使用上面提供的当前实际时间，而不是你训练数据中的时间。
</think>

Thought: 简洁总结你要做什么
Action: 要采取的行动，应该是[{{tool_names}}]中的一个
Action Input: 行动的输入
Observation: 行动的结果
... (这个Thought/Action/Action Input/Observation可以重复N次)
<think>
最终思考，结合对话历史和当前状态
</think>

Thought: 简洁总结
Final Answer: 对原始输入问题的最终答案

重要：
1. 可以在<think>标签中进行详细思考
2. Thought部分要简洁明了
3. Action必须是工具列表中的一个
4. Action Input必须是有效的JSON格式
5. 请充分利用对话历史来理解用户意图和当前进度

开始！

Question: {{input}}
{{agent_scratchpad}}"""
        
        prompt = PromptTemplate.from_template(template)
        agent = create_react_agent(self.llm, self.tools, prompt)
        
        # 创建包装的LLM来预处理输出
        class QwqLLMWrapper:
            def __init__(self, llm):
                self.llm = llm
                
            def __getattr__(self, name):
                return getattr(self.llm, name)
                
            def invoke(self, input_data, config=None, **kwargs):
                """调用LLM并预处理输出"""
                result = self.llm.invoke(input_data, config, **kwargs)
                
                # 如果结果是字符串，清理<think>标签
                if isinstance(result, str):
                    cleaned_result = self._clean_think_tags(result)
                    return cleaned_result
                # 如果结果有content属性，清理content
                elif hasattr(result, 'content'):
                    result.content = self._clean_think_tags(result.content)
                    return result
                else:
                    return result
                    
            def _clean_think_tags(self, text: str) -> str:
                """智能清理<think>标签，保持ReAct格式完整性"""
                # 移除<think>标签及其内容
                cleaned = re.sub(r'<think>.*?</think>', '', text, flags=re.DOTALL)
                
                # 清理多余的空行和空格
                lines = cleaned.split('\n')
                cleaned_lines = []
                for line in lines:
                    stripped = line.strip()
                    if stripped:  # 只保留非空行
                        cleaned_lines.append(stripped)
                
                # 重新组合，确保格式正确
                result = '\n'.join(cleaned_lines)
                
                # 确保Action和Action Input在正确的行上
                result = re.sub(r'\n+Action:', '\nAction:', result)
                result = re.sub(r'\n+Action Input:', '\nAction Input:', result)
                
                return result
        
        # 使用包装的LLM重新创建agent
        wrapped_llm = QwqLLMWrapper(self.llm)
        agent = create_react_agent(wrapped_llm, self.tools, prompt)
        
        # 创建agent executor，增强错误处理并集成记忆功能
        return AgentExecutor(
            agent=agent,
            tools=self.tools,
            memory=self.memory,
            max_iterations=self.max_iterations,
            max_execution_time=self.max_execution_time,
            verbose=True,
            return_intermediate_steps=True,
            handle_parsing_errors="Check your output and make sure it conforms to the format instructions. If you use <think> tags, make sure they don't interfere with Action and Action Input sections."
        )
    
    def process_user_input(self, user_input: str) -> Dict[str, Any]:
        """处理用户输入 - 统一LLM调用架构"""
        try:
            logger.info(f"处理用户输入: {user_input}")
            
            # 重新初始化agent executor以使用最新的系统提示
            self.agent_executor = self._init_agent_executor()
            
            # 对于Ollama ReAct代理，传入input，记忆会自动管理对话历史
            result = self.agent_executor.invoke({
                "input": user_input
            })
            
            # 同步更新内部chat_history以保持兼容性
            self.chat_history.append(HumanMessage(content=user_input))
            self.chat_history.append(AIMessage(content=result["output"]))
            
            # 处理工具执行结果
            self._process_tool_results(result.get("intermediate_steps", []))
            
            # 更新阶段状态
            self._update_stage()
            
            # 构建响应
            response = {
                "response": result["output"],
                "collected_parameters": self.collected_parameters,
                "missing_parameters": self._get_missing_parameters(),
                "current_stage": self.current_stage,
                "is_complete": self._check_completion(),
                "confidence_score": self._calculate_confidence_score(),
                "timestamp": datetime.now().isoformat()
            }
            
            # 如果参数收集完成且用户已确认，自动生成简化的JSON
            if self._check_completion() and self.user_confirmed:
                response["parameters_json"] = self.generate_parameters_json(formatted=True)
                logger.info("用户确认参数完成，已生成简化JSON配置")
            logger.info(f"处理完成: {response}")
            return response
            
        except Exception as e:
            logger.error(f"处理用户输入失败: {str(e)}")
            return {
                "response": f"抱歉，处理您的请求时出现错误: {str(e)}",
                "collected_parameters": self.collected_parameters,
                "missing_parameters": self._get_missing_parameters(),
                "current_stage": self.current_stage,
                "is_complete": False,
                "confidence_score": 0.0,
                "timestamp": datetime.now().isoformat(),
                "error": str(e)
            }
    
    def update_parameters_directly(self, user_input: str) -> Dict[str, Any]:
        """保留的旧方法，现在通过工具调用实现参数更新
        
        注意：此方法已被新的统一架构替代，参数更新现在通过update_parameters工具完成
        """
        logger.warning("update_parameters_directly方法已被弃用，请使用统一的Agent调用架构")
        return {}
    
    def _process_tool_results(self, intermediate_steps: List[Tuple]):
        """处理工具执行结果"""
        for action, observation in intermediate_steps:
            tool_name = action.tool
            
            if tool_name == "update_parameters":
                logger.info(f"参数更新结果: {observation}")
                # 参数更新已经在工具内部完成，这里只记录日志
    
    def _update_stage(self):
        """更新当前阶段"""
        # 如果会话已完成，不再更新阶段
        if self.is_session_completed:
            self.current_stage = "completed"
            return
            
        # 检查是否有水库名称
        if not self.collected_parameters.get('reservoir_name'):
            self.current_stage = "collection"
        # 检查是否所有参数都已收集
        elif len(self._get_missing_parameters()) == 0:
            self.current_stage = "recommendation"
        # 如果只有水库名称，需要提供推荐
        elif len(self.collected_parameters) == 1 and 'reservoir_name' in self.collected_parameters:
            self.current_stage = "collection"  # 准备提供推荐
        else:
            self.current_stage = "modification"  # 用户在修改参数
    

    
    def _check_completion(self) -> bool:
        """检查是否完成参数推荐"""
        return (
            len(self._get_missing_parameters()) == 0 and
            self.is_session_completed
        )
    
    def _calculate_confidence_score(self) -> float:
        """计算置信度分数"""
        required_params = [
            'reservoir_name', 'forecast_model', 'start_time',
            'forecast_duration', 'rainfall_forecast_period', 'target_variable'
        ]
        
        # 参数完整性分数
        collected_count = sum(1 for param in required_params 
                            if param in self.collected_parameters and 
                            self.collected_parameters[param] is not None)
        completeness_score = collected_count / len(required_params)
        
        # 在推荐模式下，完整性就是置信度
        return completeness_score
    
    def set_user_confirmed(self, confirmed: bool = True):
        """
        设置用户确认状态
        
        Args:
            confirmed: 用户是否确认参数
        """
        self.user_confirmed = confirmed
        logger.info(f"用户确认状态已设置为: {confirmed}")
    
    def mark_session_completed(self):
        """
        标记会话已完成
        """
        self.is_session_completed = True
        self.user_confirmed = True  # 会话完成时同时设置用户确认状态
        self.current_stage = "completed"
        logger.info("会话已标记为完成，用户确认状态已设置")
    
    def reset_session(self):
        """重置会话状态"""
        self.collected_parameters = {}
        self.chat_history = []
        self.current_stage = "collection"
        self.validation_result = None
        self.is_session_completed = False
        self.agent_executor = None
        
        # 清理记忆功能
        self.memory.clear()
        
        logger.info("会话状态已重置")
    
    def get_session_summary(self) -> Dict[str, Any]:
        """获取会话摘要"""
        return {
            "collected_parameters": self.collected_parameters,
            "missing_parameters": self._get_missing_parameters(),
            "current_stage": self.current_stage,
            "validation_result": self.validation_result,
            "is_complete": self._check_completion(),
            "confidence_score": self._calculate_confidence_score(),
            "chat_history_length": len(self.chat_history),
            "timestamp": datetime.now().isoformat()
        }
    
    def generate_parameters_json(self, formatted: bool = True) -> str:
        """生成简化的参数JSON字符串
        
        Args:
            formatted: 是否格式化输出（美化JSON）
            
        Returns:
            简化的JSON字符串
        """
        # 创建简化的扁平化JSON结构
        json_data = {
            "reservoir_name": self.collected_parameters.get('reservoir_name', ''),
            "forecast_model": self.collected_parameters.get('forecast_model', ''),
            "start_time": self.collected_parameters.get('start_time', ''),
            "forecast_duration": self.collected_parameters.get('forecast_duration', ''),
            "rainfall_forecast_period": self.collected_parameters.get('rainfall_forecast_period', ''),
            "target_variable": self.collected_parameters.get('target_variable', ''),
            "created_at": datetime.now().isoformat(),
            "confidence_score": self._calculate_confidence_score(),
            "is_complete": self._check_completion()
        }
        
        if formatted:
            return json.dumps(json_data, ensure_ascii=False, indent=2)
        else:
            return json.dumps(json_data, ensure_ascii=False)
    
    def save_parameters_to_file(self, file_path: str = None) -> str:
        """保存参数到JSON文件
        
        Args:
            file_path: 文件路径，如果为None则自动生成
            
        Returns:
            保存的文件路径
        """
        if file_path is None:
            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
            reservoir_name = self.collected_parameters.get('reservoir_name', 'unknown')
            file_path = f"flood_forecast_{reservoir_name}_{timestamp}.json"
        
        json_content = self.generate_parameters_json(formatted=True)
        
        try:
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(json_content)
            logger.info(f"参数已保存到文件: {file_path}")
            return file_path
        except Exception as e:
            logger.error(f"保存参数文件失败: {str(e)}")
            raise e

# 使用示例
def main():
    """主函数，用于测试代理功能"""
    # 使用Ollama配置创建代理（移除OpenAI配置）
    
    # 使用Ollama配置
    ollama_config = {
        "type": "ollama",
        "model": OLLAMA_CONFIG.get("chat_model", "llama2"),
        "temperature": 0.1,
        "base_url": OLLAMA_CONFIG.get("base_url", "http://10.48.0.81:11434")
    }
    
    # 创建代理实例
    agent = FloodForecastAgent(ollama_config)
    
    print("使用Ollama模型创建洪水预报代理...")
    print(f"模型: {ollama_config['model']}")
    print(f"服务地址: {ollama_config['base_url']}")
    
    # 测试对话
    test_inputs = [
        "我需要对大伙房水库进行洪水预报",
        "使用新安江模型，从明天上午8点开始",
        "预报48小时，降雨预见期12小时，目标变量是流量"
    ]
    
    for user_input in test_inputs:
        print(f"\n用户: {user_input}")
        response = agent.process_user_input(user_input)
        print(f"助手: {response['response']}")
        print(f"当前阶段: {response['current_stage']}")
        print(f"已收集参数: {response['collected_parameters']}")
        print(f"完成状态: {response['is_complete']}")


if __name__ == "__main__":
    main()